package com.xinchao.filter;


import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.xinchao.constant.RequestParameterConstant;
import com.xinchao.constant.ResponseConstant;
import com.xinchao.util.JWTUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * 登录过滤器
 *
 * @author dxy
 * @date 2018/7/5 12:39
 */
public class LoginFilter implements Filter {

	private static Logger logger = LoggerFactory.getLogger(LoginFilter.class);
	/**
	 * 登录
	 */
	private static final String LOGIN = "/web/login";
	/**
	 * 退出
	 */
	private static final String LOGOUT = "/web/logout";
	/**
	 * token
	 */
	private static final String TOKEN = "token";

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		//上下文路径
		String contextPath = httpRequest.getContextPath();
		String requestURI = httpRequest.getRequestURI();
		//login,logout直接放行
		if (requestURI.equals(contextPath + LOGIN) || requestURI.equals(contextPath + LOGOUT)) {
			chain.doFilter(httpRequest, httpResponse);
			return;
		}
		//获取token
		String token = httpRequest.getHeader(RequestParameterConstant.TOKEN);
		if (StringUtils.isBlank(token)) {
			String content = "token为空";
			generateRespnseContent(httpResponse, content, ResponseConstant.CODE_TOKEN_FAIL);
			return;
		}
		//验证token
		try {
			Map<String, Claim> claimMap = JWTUtils.parseJWTToken(token);

			if (claimMap == null && claimMap.size() == 0) {
				String content = "无效的token";
				//无效的token
				generateRespnseContent(httpResponse, content, ResponseConstant.CODE_TOKEN_FAIL);
				return;
			} else {
				Claim claim = claimMap.get(RequestParameterConstant.USER_NAME);
				if (claim == null) {
					String content = "无效的token";
					//无效的token
					generateRespnseContent(httpResponse, content, ResponseConstant.CODE_TOKEN_FAIL);
					return;
				}
				String userName = claim.asString();
				if (StringUtils.isBlank(userName)) {
					String content = "无效的token";
					//无效的token
					generateRespnseContent(httpResponse, content, ResponseConstant.CODE_TOKEN_FAIL);
					return;
				}
				chain.doFilter(httpRequest, httpResponse);
				return;
			}
		} catch (JWTVerificationException e) {
			String content = "无效的token";
			//无效的token
			logger.error("LoginFilter doFilter =======>  " + e.getMessage());
			generateRespnseContent(httpResponse, content, ResponseConstant.CODE_TOKEN_FAIL);
			return;
		}
	}

	@Override
	public void destroy() {

	}

	/**
	 * 生产响应内容
	 *
	 * @param httpResponse HttpServletResponse
	 * @param content      提示内容
	 * @param code         失败编码提示
	 * @throws IOException
	 */
	private void generateRespnseContent(HttpServletResponse httpResponse, String content, Integer code) throws IOException {
		//封装返回信息
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(ResponseConstant.RESPONSE_JSON_DATA, "");
		jsonObject.put(ResponseConstant.RESPONSE_JSON_MSG, content);
		jsonObject.put(ResponseConstant.RESPONSE_JSON_CODE, code);
		//写入ServletOutputStream
		ServletOutputStream outputStream = httpResponse.getOutputStream();
		outputStream.write(jsonObject.toJSONString().getBytes());
		outputStream.flush();
	}
}
